package cn.turboinfo.dongying.api.gateway.admin.framework.http.interceptor

import cn.turboinfo.dongying.api.entity.common.enumeration.user.UserType
import cn.turboinfo.dongying.api.entity.common.pojo.user.UserTypeRel
import cn.turboinfo.dongying.api.gateway.admin.framework.http.context.AdminRequestContextHolder
import cn.turboinfo.dongying.api.gateway.web.framework.http.annotation.PlatformScope
import cn.turboinfo.dongying.api.gateway.web.framework.http.interceptor.BaseHandlerInterceptorAdapter
import mu.KotlinLogging
import nxcloud.ext.springmvc.automapping.spring.AutoMappingRequestParameterTypeBinding
import org.springframework.stereotype.Component
import org.springframework.web.method.HandlerMethod
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import kotlin.jvm.optionals.getOrNull

/**
 * 平台用户拦截器
 */
@Component
class AdminPlatformScopeInterceptor(
    private val autoMappingRequestParameterTypeBinding: AutoMappingRequestParameterTypeBinding,
) : BaseHandlerInterceptorAdapter() {
    private val logger = KotlinLogging.logger {}

    @OptIn(ExperimentalStdlibApi::class)
    override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean {
        if (handler is HandlerMethod) {
            val requestContext =
                AdminRequestContextHolder.current()

            if (requestContext.isLogin) {

                getAnnotation(
                    handler,
                    PlatformScope::class.java, true
                ).getOrNull()
                    ?: autoMappingRequestParameterTypeBinding.getAnnotation(
                        handler.method,
                        PlatformScope::class.java, true
                    )
                    ?: return true
                
                try {

                    if (requestContext.session.userTypeRelList
                            .stream()
                            .noneMatch { userTypeRel -> userTypeRel.userType === UserType.Platform }
                    ) {
                        throw RuntimeException("当前请求用户不是平台用户")
                    }

                    // 设置会话中的平台ID
                    requestContext.platformId = requestContext.session.userTypeRelList.stream()
                        .filter { userTypeRel -> userTypeRel.userType === UserType.Platform }
                        .map(UserTypeRel::getObjectId)
                        .findFirst().orElse(null)

                } catch (e: NumberFormatException) {
                    throw RuntimeException("请求的平台编码不正确")
                }
            }
        }

        return true
    }
}